#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>

using namespace std;

int tickets = 1000;

sem_t sem;

void *Routine(void *args)
{
    while(true)
    {
        // usleep(1000);
        sem_wait(&sem);
        if(tickets > 0)
        {
            usleep(1000); //等待线程时间片到期，加大线程切换概率
            cout << "get a tickets: " << tickets << endl;
            tickets--;
            sem_post(&sem); 
        }  
        else
        {
            sem_post(&sem);
            break;
        }
    }
    pthread_exit((void*)6666);
}

// void *Routine(void *args)
// {
//     while(true)
//     {
//         // usleep(1000);
//         if(tickets > 0)
//         {
//             usleep(1000); //等待线程时间片到期，加大线程切换概率
//             cout << "get a tickets: " << tickets << endl;
//             tickets--;
//         }  
//         else
//         {
//             break;
//         }
//     }
//     pthread_exit((void*)6666);
// }

int main()
{
    sem_init(&sem, 0, 1);

    pthread_t tid1, tid2, tid3, tid4, tid5;
    pthread_create(&tid1, nullptr, Routine, nullptr);
    pthread_create(&tid2, nullptr, Routine, nullptr);
    pthread_create(&tid3, nullptr, Routine, nullptr);
    pthread_create(&tid4, nullptr, Routine, nullptr);
    pthread_create(&tid5, nullptr, Routine, nullptr);


    pthread_join(tid1, nullptr);
    pthread_join(tid2, nullptr);
    pthread_join(tid3, nullptr);
    pthread_join(tid4, nullptr);
    pthread_join(tid5, nullptr);

    sem_destroy(&sem);

    return 0;
}

// #include <iostream>
// #include <string>
// #include <unistd.h>
// #include <pthread.h>

// int tickets = 20000;
// void* TicketGrabbing(void* arg)
// {
// 	std::string name = (char*)arg;
// 	while (true){
// 		if (tickets > 0){
// 			usleep(1000);
// 			std::cout << name << " get a ticket, tickets left: " << --tickets << std::endl;
// 		}
// 		else{
// 			break;
// 		}
// 	}
// 	std::cout << name << " quit..." << std::endl;
// 	pthread_exit((void*)0);
// }

// int main()
// {
// 	pthread_t tid1, tid2, tid3, tid4;
// 	pthread_create(&tid1, nullptr, TicketGrabbing, (void*)"thread 1");
// 	pthread_create(&tid2, nullptr, TicketGrabbing, (void*)"thread 2");
// 	pthread_create(&tid3, nullptr, TicketGrabbing, (void*)"thread 3");
// 	pthread_create(&tid4, nullptr, TicketGrabbing, (void*)"thread 4");
	
// 	pthread_join(tid1, nullptr);
// 	pthread_join(tid2, nullptr);
// 	pthread_join(tid3, nullptr);
// 	pthread_join(tid4, nullptr);
// 	return 0;
// }
